package com.liangwj.springbootquickstart.jdk8.functionalInterface;

import org.springframework.util.Assert;

import java.util.function.Consumer;
import java.util.function.Function;
import java.util.function.Predicate;

/**
 * <b>Description:</b> Java函数式接口 <br/>
 * @author Lingwenjun
 * @date 2019/1/11-15:49
 * @version 1.0
 */
public class FunctionalInterfaceDemo {

    /**
     * Consumer是一个函数式编程接口； 顾名思义，Consumer的意思就是消费，即针对某个东西我们来使用它，
     * 因此它包含有一个有输入而无输出的accept接口方法；
     * 除accept方法，它还包含有andThen这个方法；
     * default Consumer<T> andThen(Consumer<? super T> after) {
     *         Objects.requireNonNull(after);
     *         return (T t) -> { accept(t); after.accept(t); };
     * }
     * 可见这个方法就是指定在调用当前Consumer后是否还要调用其它的Consumer；
     */
    //使用示例
    public static void consumerTest() {
        Consumer f = System.out::println;
        Consumer f1 = n -> System.out.println( n + "-f1");

        //执行完F后再执行f1 的Accept方法
        f.andThen(f1).accept("test");

        //连续执行f的Accept方法
        f.andThen(f).andThen(f).andThen(f).accept("test1");
    }

    /**
     * Function也是一个函数式编程接口；它代表的含义是“函数”，而函数经常是有输入输出的，因此它含有一个apply方法，包含一个输入与一个输出；
     * 除apply方法外，它还有compose与andThen及indentity三个方法，其使用见下述示例；
     * andThen --after
     * compose --before
     */
    //使用示例
    public static void functionTest() {
        Function<Integer, Integer> function = s -> s++;
        Function<Integer, Integer> function1 = s -> s * 2;
        //下面表示在执行function时,先执行function1, 并且执行function时使用function1的输出当做输入
        //Integer a = function1.apply(1);
        //System.out.println(function.apply(a));
        System.out.println(function.compose(function1).apply(1));

        //标识function执行Apply后的返回值当做输入的再去执行function1
        System.out.println(function.andThen(function1).apply(1));

        //identity方法会返回一个不进行任何处理的Function,即输出与输入值相等
        System.out.println(Function.identity().apply("a"));
    }

    /**
     * Predicate为函数式接口，predicate的中文意思是“断定”，即判断的意思，判断某个东西是否满足某种条件；
     * 因此它包含test方法，根据输入值来做逻辑判断，其结果为True或者False。
     * 它的使用方法示例如下：
     */
    //使用示例
    public static void predicateTest() {
        Predicate<String> a = s -> s.equals("test");
        Predicate<String> b = s -> s.startsWith("t");

        //negate:对原来的Predicate做取反处理
        Assert.isTrue(!a.negate().test("test"), "not true");

        //and: 针对同一输入值, 多个Predicate均返回true时返回true, 否则返回false
        Assert.isTrue(a.and(b).test("test"), "not true!");

        //or: 针对同一输入值, 多个Predicate有一个返回true则返回true, 否则返回false;
        Assert.isTrue(a.or(b).test("test"), "not true!");
    }

    public static void main(String[] args) {
        //FunctionalInterfaceDemo.consumerTest();
        //FunctionalInterfaceDemo.functionTest();
        FunctionalInterfaceDemo.predicateTest();
    }

}
